// *** ADDED BY HEADER FIXUP ***
#include <wx/gdicmn.h>
#include <wx/menuitem.h>
#include <wx/utils.h>
// *** END ***
/***************************************************************
 * Name:      ClientMain.cpp
 * Purpose:   Code for Application Frame
 * Author:    sleepiforest (248023406@qq.com)
 * Created:   2011-11-28
 * Copyright: sleepiforest (http://weibo.com/sleepiforest)
 * License:
 **************************************************************/

#include "ClientMain.h"
#include <wx/msgdlg.h>
#include <wx/xml/xml.h>
#include <wx/sstream.h>
//(*InternalHeaders(ClientFrame)
#include <wx/intl.h>
#include <wx/string.h>
//*)
#include "Mysocket.h"
//helper functions
enum wxbuildinfoformat {
    short_f, long_f };

wxString wxbuildinfo(wxbuildinfoformat format)
{
    wxString wxbuild(wxVERSION_STRING);

    if (format == long_f )
    {
#if defined(__WXMSW__)
        wxbuild << _T("-Windows");
#elif defined(__UNIX__)
        wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
        wxbuild << _T("-Unicode build");
#else
        wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
    }

    return wxbuild;
}
const long ClientFrame::SOCKET_ID = wxNewId();
//(*IdInit(ClientFrame)
const long ClientFrame::ID_PANEL3 = wxNewId();
const long ClientFrame::ID_TEXTCTRL1 = wxNewId();
const long ClientFrame::ID_PANEL2 = wxNewId();
const long ClientFrame::ID_TEXTCTRL2 = wxNewId();
const long ClientFrame::ID_PANEL1 = wxNewId();
const long ClientFrame::idMenuQuit = wxNewId();
const long ClientFrame::idMenuAbout = wxNewId();
const long ClientFrame::ID_STATUSBAR1 = wxNewId();
//*)

BEGIN_EVENT_TABLE(ClientFrame,wxFrame)
	EVT_SOCKET(SOCKET_ID,  ClientFrame::OnSocketEvent)
    //(*EventTable(ClientFrame)
    //*)
END_EVENT_TABLE()

ClientFrame::ClientFrame(wxWindow* parent):
    connectDlg(0),queryDlg(0)
{
    //(*Initialize(ClientFrame)
    wxMenuItem* MenuItem2;
    wxMenuItem* MenuItem1;
    wxBoxSizer* BoxSizer2;
    wxMenu* Menu1;
    wxBoxSizer* BoxSizer1;
    wxMenuBar* MenuBar1;
    wxMenu* Menu2;

    Create(parent, wxID_ANY, _("手机导购测试用~~"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("wxID_ANY"));
    BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
    BoxSizer2 = new wxBoxSizer(wxVERTICAL);
    Panel3 = new wxPanel(this, ID_PANEL3, wxDefaultPosition, wxSize(487,24), wxTAB_TRAVERSAL, _T("ID_PANEL3"));
    BoxSizer2->Add(Panel3, 0, wxEXPAND|wxALIGN_LEFT|wxALIGN_BOTTOM, 5);
    txLog = new TextLog(this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxSize(487,231), wxTE_AUTO_SCROLL|wxTE_MULTILINE|wxTE_READONLY|wxTE_LEFT, wxDefaultValidator, _T("ID_TEXTCTRL1"));
    BoxSizer2->Add(txLog, 1, wxEXPAND|wxALIGN_LEFT|wxALIGN_BOTTOM, 5);
    Panel2 = new wxPanel(this, ID_PANEL2, wxDefaultPosition, wxSize(121,26), wxTAB_TRAVERSAL, _T("ID_PANEL2"));
    BoxSizer2->Add(Panel2, 0, wxEXPAND|wxALIGN_LEFT|wxALIGN_BOTTOM, 5);
    txEdit = new wxTextCtrl(this, ID_TEXTCTRL2, wxEmptyString, wxDefaultPosition, wxSize(487,70), wxTE_PROCESS_ENTER, wxDefaultValidator, _T("ID_TEXTCTRL2"));
    txEdit->SetFocus();
    BoxSizer2->Add(txEdit, 0, wxEXPAND|wxALIGN_LEFT|wxALIGN_BOTTOM, 5);
    Panel1 = new wxPanel(this, ID_PANEL1, wxDefaultPosition, wxSize(487,25), wxTAB_TRAVERSAL, _T("ID_PANEL1"));
    BoxSizer2->Add(Panel1, 0, wxEXPAND|wxALIGN_LEFT|wxALIGN_BOTTOM, 5);
    BoxSizer1->Add(BoxSizer2, 1, wxEXPAND|wxALIGN_LEFT|wxALIGN_BOTTOM, 5);
    SetSizer(BoxSizer1);
    MenuBar1 = new wxMenuBar();
    Menu1 = new wxMenu();
    MenuItem1 = new wxMenuItem(Menu1, idMenuQuit, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
    Menu1->Append(MenuItem1);
    MenuBar1->Append(Menu1, _("&File"));
    Menu2 = new wxMenu();
    MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
    Menu2->Append(MenuItem2);
    MenuBar1->Append(Menu2, _("Help"));
    SetMenuBar(MenuBar1);
    StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
    int __wxStatusBarWidths_1[1] = { -1 };
    int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
    StatusBar1->SetFieldsCount(1,__wxStatusBarWidths_1);
    StatusBar1->SetStatusStyles(1,__wxStatusBarStyles_1);
    SetStatusBar(StatusBar1);
    BoxSizer1->Fit(this);
    BoxSizer1->SetSizeHints(this);

    Connect(ID_TEXTCTRL2,wxEVT_COMMAND_TEXT_ENTER,(wxObjectEventFunction)&ClientFrame::OntxEditText);
    Connect(idMenuQuit,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&ClientFrame::OnQuit);
    Connect(idMenuAbout,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&ClientFrame::OnAbout);
    //*)
    queryDlg.SetParent(this);
}

ClientFrame::~ClientFrame()
{
	if(sock) sock->Destroy();
	//wxMessageBox(_("delete!"));
    //(*Destroy(ClientFrame)
    //*)
}

void ClientFrame::Show()
{
    if((sock=connectDlg.GetConnection(this))!=NULL)
    {
        serverName = connectDlg.GetServerName();
        name = connectDlg.GetUserName();
        sock->SetEventHandler(*this,SOCKET_ID);
        sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
        sock->Notify(true);
        if(sock->WaitForRead(0)) OnRead();
        txEdit->SetFocus();
        wxFrame::Show();
    }
    else
    {
        Destroy();
    }
}


void ClientFrame::OnQuit(wxCommandEvent& event)
{
    Close();
}

void ClientFrame::OnAbout(wxCommandEvent& event)
{
    wxString msg = wxbuildinfo(long_f);
    wxMessageBox(msg, _("Welcome to..."));
}
void ClientFrame::SendString(wxString msg)
{
    if(!Mysocket::SendString(sock,msg))
    {
        wxMessageBox(_("连接超时!! 退出程序!!"));
        Close();
    }
}

void ClientFrame::OntxEditText(wxCommandEvent& event)
{
	wxString msg = _("<Message><Content>") + txEdit->GetValue() + _("</Content></Message>");
	SendString(msg);
	txLog->AddLog(name,txEdit->GetValue());
	txEdit->Clear();
}

void ClientFrame::OnSocketEvent(wxSocketEvent& event)
{
	//wxMessageBox(_("消息"));
	switch(event.GetSocketEvent())
	{
		case wxSOCKET_INPUT: OnRead();break;
		case wxSOCKET_LOST: OnLost();break;
		default: wxMessageBox(_("未知消息类型"));
	}
}
void ClientFrame::OnRead()
{
	wxString msg;
	Mysocket::ReceiveString(sock,msg);
	//wxMessageBox(_("Receive String: ")+msg);
    wxStringInputStream rev(msg);
	wxXmlDocument doc(rev);
	if(!doc.IsOk()) return;
	wxXmlNode *node = doc.GetRoot();
	//wxMessageBox(_("Receive: ")+node->GetName());
	while(node)
    {
        if(node->GetName()==_("Setting"))
        {
            OnSetting(node->GetChildren());
        }
        else if(node->GetName()==_("Respond"))
        {
            OnRespond(node->GetChildren());
        }
        else if(node->GetName()==_("Message"))
        {
            OnMessage(node->GetChildren());
            //txLog->AddLog(serverName,);
        }
        node = node->GetNext();
    }
}
void ClientFrame::OnRespond(wxXmlNode *node)
{
	if(!connectDlg.IsAddMsg())
	{
		txLog->AddLog(serverName, wxT("请继续问别的问题"));
	}
	else
	{
		wxString query;
		while(node)
		{
			if(node->GetName()==wxT("Query"))
			{
				query = node->GetNodeContent();
			}
			node = node->GetNext();
		}
		if(query.empty()) return;
		if(queryDlg.ShowModal(query)==wxID_OK)
		{
			wxString res = wxT("<Respond>\n");
			res += wxT("<QueryType>") + queryDlg.queryType + wxT("</QueryType>\n");
			res += wxT("<Query>") + query + wxT("</Query>\n");
			if(queryDlg.IsThat()) res += wxT("<That>") + txLog->LastMsg(serverName) + wxT("</That>\n");
			if(!queryDlg.answer.empty()) res += wxT("<Answer>") + queryDlg.answer + wxT("</Answer>\n");
			res += wxT("</Respond>\n");
			SendString(res);
		}
	}
    txEdit->SetFocus();
}

void ClientFrame::OnSetting(wxXmlNode *node)
{
    //wxMessageBox(_("setting"));
    while(node)
    {
        if(node->GetName()==_("AddQueryType"))
        {
            queryDlg.AddQueryType(node->GetNodeContent());
        }
        else if(node->GetName()==_("RemoveQueryType"))
        {
            queryDlg.RemoveQueryType(node->GetNodeContent());
        }
        node = node->GetNext();
    }
    SendString(_("<Ack>Setting</Ack>"));/**< 异步应答通讯，确保先收到设定后传输消息 */
}
void ClientFrame::OnMessage(wxXmlNode* node)
{
    wxString content;
    while(node)
    {
        if(node->GetName()==_("Content"))
        {
            txLog->AddLog(serverName,node->GetNodeContent());
        }
        node = node->GetNext();
    }
}

void ClientFrame::OnLost()
{
	wxMessageBox(_("连接中断!! 退出程序!!"));
	Close();
}
